package main;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Scanner;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import subscribersManagement.Entitled;
import subscribersManagement.Subscriber;
import subscribersManagement.UtilsDate;

import jpaUtils.JPAUtil;

import exceptions.BadParametersException;
import exceptions.BookExistsException;
import exceptions.SubscriberExistsException;

import loansManagement.LoanDAO;

import booksManagement.*;

public class Main
{

	/**
	 * @param args
	 * @throws BadParametersException 
	 * @throws BookExistsException 
	 */
	public static void main(String[] args) throws BadParametersException, BookExistsException
	{
		//Init
		Scanner scanString = new Scanner(System.in);
		Scanner scanInt = new Scanner(System.in);
    Library library = new Library();
    List<String> authors1= new ArrayList<String>();
  	List<String> authors2= new ArrayList<String>();
    //Class libClass = library.getClass();
    //MediaDAO medias = new MediaDAO();
    EntityManager em;
		EntityTransaction tx;
		
		//Initial Data for tests
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		tx.begin();
		
		authors1.add("Elmasri");
		authors1.add("Navathe");
		authors2.add("Peter Gulutzan");
		authors2.add("Trudy Pelzer");
		Book b1 = new Book("Fundamentals of Database Systems", authors1, new GregorianCalendar(), "0-321-20228-4");
		Book b2 = new Book("SQL-99 Complete, Really", authors2, new GregorianCalendar(), "0-87930-568-1");
		DVD d1 = new DVD("La guerre des boutons", new GregorianCalendar(),"0654744657",2);
		DVD d2 = new DVD("Microcosmos", new GregorianCalendar(),"136658783", 1);
		Book b3 = new Book("Pandore menacée", new ArrayList<String>(), UtilsDate.asCalendar(UtilsDate.stringToDate("12/11/2004")), "978-2-8112-0036-7", 5);
		Subscriber 	s1 = new Subscriber("Vincent", "Airo", new GregorianCalendar(1960, 12, 13));
		Subscriber 	s2 = new Subscriber("Betina", "Chtilfiz", new GregorianCalendar(1965, 02, 25));
		Entitled 	s3 = new Entitled("Victor", "Chtilfiz", new GregorianCalendar(1997, 02, 20), s2);
		Entitled 	s4 = new Entitled("Luisa", "Chtilfiz", new GregorianCalendar(1993, 07, 30), s2);
		
		try{
			library.addMedia(b3);
			library.addMedia(b2);
			library.addMedia(b1);
			library.addMedia(d2);
			library.addMedia(d1);
			library.addSubscriber(s1);
			library.addSubscriber(s2);
			library.addSubscriber(s3);
			library.addSubscriber(s4);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		tx.commit();
		JPAUtil.closeEntityManager();
		
		
		//Launch
		while(true){
			em= JPAUtil.getEntityManager();
			tx=em.getTransaction();
			System.out.println("What do you want to do ?");
			System.out.println("1. AddBook");
			System.out.println("2. AddDvd");
			System.out.println("3. AddSubscriber");
			System.out.println("4. AddMediaCopies");
			System.out.println("5. DeleteMedia");
			System.out.println("6. DeleteCopy");
			System.out.println("7. DeleteSubscriber");
			System.out.println("8. Lend a Media");
			System.out.println("9. Reserve a Media");
			System.out.println("10. Cancel Reservation");
			System.out.println("11. Return a media");
			System.out.println("12. List Medias");
			System.out.println("13. List Loans");
			System.out.println("14. List Subscribers");
			System.out.println("15. List Reservations");
			int choice = scanInt.nextInt();
			
			
			switch(choice){
				case 1:
					System.out.println("====Add Book====");
					System.out.println("AddBook : title ?");
		  		String title = scanString.nextLine();
		  		System.out.println("AddBook : author ?");
		  		String author = scanString.nextLine();
		  		ArrayList<String> authors = new ArrayList<String>();
		  		authors.add(author);
		  		System.out.println("AddBook : isbn ?");
		  		String isbn = scanString.nextLine();
		  		System.out.println("editionDate (dd/mm/yyyy) ?");
		  		Date edDate = UtilsDate.stringToDate(scanString.nextLine());
		  		GregorianCalendar editionDate = UtilsDate.asCalendar(edDate);
		  		System.out.println("AddBook : number of copies ?");
		  		int copyAmount = scanInt.nextInt();
		  		try{
		  			tx.begin();
		  			library.addMedia(new Book(title, authors, editionDate, isbn, copyAmount));
		  			tx.commit();
			  		System.out.println("Book added :" + library.getMedias().get(isbn));
		  			
		  		}catch(Exception e){
		  			e.printStackTrace();
		  		}
		  		JPAUtil.closeEntityManager();
		  		break;
		  		
				case 2:
					System.out.println("====Add DVD====");
					System.out.println("AddDvd : title ?");
		  		String dvdtitle = scanString.nextLine();
		  		System.out.println("AddBook : isan ?");
		  		String isan = scanString.nextLine();
		  		System.out.println("editionDate (dd/mm/yyyy) ?");
		  		Date ediDate = UtilsDate.stringToDate(scanString.nextLine());
		  		GregorianCalendar dvdEditionDate = UtilsDate.asCalendar(ediDate);
		  		System.out.println("AddDvd : number of copies ?");
		  		int dvdcopyAmount = scanInt.nextInt();
		  		try{
		  			tx.begin();
		  			library.addMedia(new DVD(dvdtitle, dvdEditionDate, isan, dvdcopyAmount));
		  			tx.commit();
			  		System.out.println("Dvd added :" + library.getMedias().get(isan));
		  			
		  		}catch(Exception e){
		  			e.printStackTrace();
		  		}
		  		JPAUtil.closeEntityManager();	  				  		
		  		break;
		  		
		  	//Add subscriber
				case 3:
					System.out.println("====Add Subscriber====");
					System.out.println("First Name ?");
					String firstName = scanString.nextLine();
					System.out.println("Last Name ?");
					String lastName = scanString.nextLine();
					System.out.println("birthDate (dd/mm/yyyy) ?");
					Date birthDate = UtilsDate.stringToDate(scanString.nextLine());
					GregorianCalendar birthDAte = UtilsDate.asCalendar(birthDate);
					try{
						Subscriber s = new Subscriber(firstName, lastName, birthDAte);
						
						
						tx.begin();
						
						long subscriber_id=library.addSubscriber(s);
						tx.commit();
						System.out.println("Subscriber added : " + library.getSubscribers().get(subscriber_id));
						}catch(BadParametersException e){
							System.out.println("Problem with parameters");
							e.printStackTrace();
						}
          catch (SubscriberExistsException e)
            {
	            e.printStackTrace();
            }
					JPAUtil.closeEntityManager();
					break;
					
				case 4:
					System.out.println("====Add Copies of a Media====");
					System.out.println("Media isbn/isan ?");
					String id = scanString.nextLine();
					System.out.println("Number of copies to add ?");
					int n = scanInt.nextInt();
					try{
						tx.begin();
						Media m =library.getMedias().get(id);
						library.addMediaCopy(m, n);
						tx.commit();
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 5:
					System.out.println("====Delete Media====");
					System.out.println("isbn/isan of the media to delete ?");
					id = scanString.nextLine();
					try{
						tx.begin();
						Media m =library.getMedias().get(id);
						library.deleteMedia(m);
						tx.commit();
						System.out.println(m + "deleted");
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 6:
					System.out.println("====Delete Copy====");
					System.out.println("id of the copy to delete ?");
					long iD = scanInt.nextInt();
					try{
						tx.begin();
						Copy c =library.getCopies().get(iD);
						library.deleteCopy(c);
						tx.commit();
						System.out.println(c + "deleted");
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 7:
					System.out.println("====Delete Subscriber====");
					System.out.println("subscriber number of the subscriber to delete ?");
					iD = scanInt.nextLong();
					try{
						tx.begin();
						Subscriber s =library.getSubscribers().get(iD);
						library.deleteSubscriber(s);
						tx.commit();
						System.out.println(s + "deleted");
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 8:
					System.out.println("====Lend media====");
					System.out.println("id of the copy to lend ?");
					iD = scanInt.nextLong();
					System.out.println("subscriber number ?");
					long number = scanInt.nextLong();
					try{
						tx.begin();
						Copy c = library.getCopies().get(iD);
						Subscriber s =library.getSubscribers().get(number);
						Calendar returnDate = library.lend(c, s);
						tx.commit();
						System.out.println("Return Date : " + UtilsDate.dateToString(returnDate.getTime()));
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 9:
					System.out.println("====Reserve Media====");
					System.out.println("isbn/isan of the media to reserve ?");
					String isbn_isan = scanString.nextLine();
					System.out.println("subscriber number ?");
					number = scanInt.nextLong();
					try{
						tx.begin();
						Subscriber s =library.getSubscribers().get(number);
						Media m = library.getMedias().get(isbn_isan);
						library.reserve(m, s);
						tx.commit();
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
				
				case 10:
					System.out.println("====Cancel Reservation====");
					System.out.println("Isbn/isan ?");
					isbn_isan = scanString.nextLine();
					System.out.println("Subscriber number ?");
					number = scanInt.nextLong();
					try{
						tx.begin();
						Subscriber s =library.getSubscribers().get(number);
						Media m = library.getMedias().get(isbn_isan);
						library.cancelReservation(m, s);
						tx.commit();
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 11:
						System.out.println("====Return copy====");
						System.out.println("id of the copy to return ?");
						iD = scanInt.nextLong();
						try{
							tx.begin();
							Copy c = library.getCopies().get(iD);
							library.returnCopy(c);
							tx.commit();
							System.out.println(c + " returned");
						}catch(Exception e){
							e.printStackTrace();
						}
						JPAUtil.closeEntityManager();
						break;
						
				case 12:
					System.out.println("====List Medias====");
					try{
						tx.begin();
						System.out.println(library.getMedias().toString());
						tx.commit();
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 13:
					System.out.println("====List Loans====");
					try{
						tx.begin();
						System.out.println(library.getLoans().toString());
						tx.commit();
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
				case 14:
					System.out.println("====List Subscribers====");
					try{
						tx.begin();
						System.out.println(library.getSubscribers().toString());
						tx.commit();
					}catch(Exception e){
						e.printStackTrace();
					}
					JPAUtil.closeEntityManager();
					break;
					
			}
			/*tx=em.getTransaction();
			tx.begin();
  		//System.out.println("What do you want to do ?");
  		System.out.println("AddBook : title ?");
  		String title = scanString.nextLine();
  		System.out.println("AddBook : author ?");
  		String author = scanString.nextLine();
  		ArrayList<String> authors = new ArrayList<String>();
  		authors.add(author);
  		System.out.println("AddBook : isbn ?");
  		String isbn = scanString.nextLine();
  		Book b = new Book(title, authors, new GregorianCalendar(),isbn);
  		
  		try{
  			library.addMedia(b);
  		} catch (Exception pe) {
				System.err.println("Exception when persisting data");
				JPAUtil.closeEntityManager();
				pe.printStackTrace();
			}
  		
  		System.out.println("medias : " + library.getMedias().getContent().size());
  		System.out.println(library.getMedias().getContent());
  		tx.commit();
  		JPAUtil.closeEntityManager();


  	    //Class myClass = Class.forName(scanString.nextLine());

  	    /*String methodName = scanString.nextLine();
  	    System.out.println("Input the parameters of the method");
  	    if (scanString.nextLine()== "null"){
  	    	Method method = libClass.getMethod(methodName, (Class<?>[]) null);
  	    }else{
  	    	
  	    }
  	    //library.getClass().getMethod(scanString.nextLine(), (Class<?>[]) null);
  	    System.out.println(method.invoke(library,(Object[]) null));*/

      }

	}

}
